# coding: utf-8

import time

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from selenium_listener import SeleniumListener

from spider import logger


class SeleniumHandler(object):

    def __init__(self):
        # chrome_options = webdriver.ChromeOptions()
        # chrome_options.add_argument('--user-data-dir=/home/yehun/.config/chromium/Default ')
        # chrome_options.add_argument('--enable-console ')
        # self.driver = webdriver.Chrome(chrome_options=chrome_options)
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(30)
        listener = SeleniumListener()
        self.browser = listener.register(self.driver)

    def maximize_window(self):
        self.browser.maximize_window()

    def add_header(self, header):
        options = webdriver.ChromeOptions()
        for (key, value) in header.items():
            options.add_argument('{0}="{1}"'.format(key, value))
        return self

    def add_cookie(self, cookies):
        self.browser.delete_all_cookies()
        for cookie_dic in cookies:
            self.browser.add_cookie(cookie_dic)
        return self

    def delete_all_cookie(self):
        self.browser.delete_all_cookies()
        return self

    def get_cookies(self):
        return self.browser.get_cookies()

    def get(self, url):
        self.browser.get(url)
        return self

    def get_current_url(self):
        return self.browser.current_url

    def get_page_source(self):
        return self.browser.page_source

    def get_screenshot_as_png(self):
        return self.browser.get_screenshot_as_png()

    def get_windows(self):
        return self.browser.window_handles

    def get_current_window(self):
        return self.browser.current_window_handle

    def find_element(self, by=By.ID, value=None):
        return self.browser.find_element(by, value)

    def get_element(self, xpath_string):
        return self.browser.find_element_by_xpath(xpath_string)

    def get_elements(self, xpath_string):
        return self.browser.find_elements_by_xpath(xpath_string)

    def get_element_text(self, xpath_string):
        element = self.get_element(xpath_string)
        if element:
            return element.text
        return None

    def get_element_attribute(self, xpath_string, name):
        element = self.get_element(xpath_string)
        if element:
            return element.get_attribute(name)
        return None

    def get_action_chains(self):
        return ActionChains(self.browser)

    def jump_page(self, url):
        self.execute_script('window.location.href="{0}";'.format(url))
        time.sleep(1)
        return self

    def switch_to_default_content(self):
        self.browser.switch_to_default_content()
        return self

    def switch_to_frame(self, frame):
        self.browser.switch_to_frame(frame)
        return self

    def switch_to(self):
        self.browser.switch_to()
        return self

    def switch_to_window(self, window):
        self.browser.switch_to_window(window)
        return self

    def switch_to_window_by_index(self, index):
        if index < 0:
            index = 0
        window_handler_list = self.get_windows()
        length = len(window_handler_list) - 1
        if index > length:
            index = length
        self.browser.switch_to_window(window_handler_list[index])
        return self

    def switch_to_prev_window(self):
        windows = self.get_windows()
        size = len(windows)
        if size > 0:
            self.close().switch_to_window(windows[size-1]).refresh()
        return self

    def execute_script(self, string):
        return self.browser.execute_script(string)

    def execute_async_script(self, string):
        return self.browser.execute_async_script(string)

    def loading(self):
        self.execute_script('window.scrollTo(0, document.body.scrollHeight)')
        time.sleep(1)
        return self

    def back(self):
        self.browser.back()
        return self

    def forward(self):
        self.browser.forward()
        return self

    def refresh(self):
        self.browser.refresh()
        return self

    def wait(self, locator, timeout=60):
        driver_wait = WebDriverWait(self.driver, timeout, 0.5)
        driver_wait.until(EC.presence_of_element_located(locator))
        # driver_wait.until(lambda x: x.find_element_by_id("id").is_displayed())

    def exists(self, by=By.ID, value=None):
        try:
            return self.find_element(by, value) is not None
        except NoSuchElementException, e:
            logger.error(e)
        return False

    def close(self, window = None):
        if window:
            self.browser.switch_to_window(window)
        self.browser.close()
        return self

    def close_all(self):
        window_list = self.get_windows()
        for window in window_list:
            self.switch_to_window(window)
            self.browser.close()
        return self

    def exit(self):
        self.browser.quit()
